/* 
 * File:   JBuffer.cpp
 * Author: johnneyshi
 * 
 * Created on 2013年2月20日, 下午3:25
 */

#include <string.h>

#include "JBuffer.h"
#include "JUuid.h"


JBuffer::JBuffer(std::string _bufferPath) : bufferPath(_bufferPath),usedBuffSize(0),
        pFile(NULL),buffSize(10),alreadyGetSize(0),getCount(0),isInUsed(false)
{
    buff = new char[buffSize];
}

//JBuffer::JBuffer(const JBuffer& orig) {
//}


JBuffer::~JBuffer() 
{
    delete [] buff;
    if(pFile != NULL)
    {
        pFile->CloseStream();
    }
}

int JBuffer::Get(char* _buff, int size)
{
    if(pFile != NULL)
    {
        int n = -1;
        if((n = GetFromFile(_buff,size)) < size)
        {
            int tmptmp = size - n;
            int nn = GetFromBuff(_buff+n,tmptmp);
            return n + nn;
        }
        else
        {
            return n;
        }
    }
    else
    {
        return GetFromBuff(_buff,size);
    }
}

int JBuffer::GetFromBuff(char* _buff, int size)
{
    int restCount = usedBuffSize - alreadyGetSize;
    if(restCount == 0)
    {
        isInUsed = false;//如果数据取完，置isInUsed为false
        usedBuffSize = 0;
        alreadyGetSize = 0;
        getCount = 0;
        return restCount;
    }
    if(size >= restCount)
    {
        memcpy(_buff,buff+alreadyGetSize,restCount);
        alreadyGetSize += restCount;
        isInUsed = false;//如果数据取完，置isInUsed为false
        usedBuffSize = 0;
        alreadyGetSize = 0;
        getCount = 0;
        return restCount;
    }
    else
    {
        memcpy(_buff,buff+alreadyGetSize,size);
        alreadyGetSize += size;
        return size;
    }
}

int JBuffer::GetFromFile(char* _buff, int size)
{
    if(pFile != NULL)
    {
        if(getCount == 0)
        {
            pFile->fs.seekg(0,std::ios::beg);
        }
        pFile->fs.read(_buff,size);
        if(pFile->fs.eof())
        {
            size = pFile->fs.gcount();
            CleanFile();
            return size;
        }
        ++getCount;
        return size;
    }
}

void JBuffer::Put(const char* _buff, int size)
{
    isInUsed = true;
    if(size > buffSize)
    {
        Flush();
        PutToFile(_buff,size);
    }
    else if(usedBuffSize + size > buffSize)
    {
        Flush();
        memcpy(buff+usedBuffSize,_buff,size);
        usedBuffSize += size;
    }
    else
    {
        memcpy(buff+usedBuffSize,_buff,size);
        usedBuffSize += size;
    }
}

//直接把buff写入文件
void JBuffer::PutToFile(const char* _buff, int size)
{
    pFile->fs.write(_buff,size);
}

void JBuffer::Flush()
{
    if(pFile == NULL)
    {
        pFile = new JFile(this->bufferPath + "/" + JUuid::ToString());
        pFile->OpenStream(std::ios::out | std::ios::binary);
        pFile->CloseStream();
        pFile->OpenStream(std::ios::out | std::ios::in | std::ios::binary);
    }
    pFile->fs.write(buff,usedBuffSize);
    usedBuffSize = 0;
}

void JBuffer::CleanFile()
{
    if(pFile != NULL)
    {
        pFile->CloseStream();
        pFile->OpenStream(std::ios::out | std::ios::in | std::ios::binary | std::ios::trunc);
    }
}

bool JBuffer::IsInUsed()
{
    return isInUsed;
}

void JBuffer::SetInUsed()
{
    this->isInUsed = true;
}